import React, { PureComponent, Fragment } from 'react';
import { Modal, Alert, Tag, Form, Badge, Row, Table, Divider, Button, Input, Select, Popover, message } from 'antd';
// import { connect } from 'dva';
import lodash from 'lodash';
// import PageHeaderLayout from '../../layouts/PageHeaderLayout';
import Ellipsis from '../../components/Ellipsis';
import { ResourcesTypeArray, SorterOrderMapper, ResourcesTypeMapper, TargetExistMapper, NeedAuthorizationMapper, NeedAuthorizationArray } from '../../utils/enum';
import { cutOffStr } from '../../utils/utils';
import { ModelInitState } from '../../utils/constant';
import { findByPage } from '../../services/manage-by-permission-controller';
import { findPermissionStrByRole } from '../../services/manage-by-query-controller';
// import classNames from 'classnames';
import styles from './RoleBindPermission.less';

// 初始状态
const InitState = {
  // 查询状态
  queryLoading: false,
  // 当前选择的角色
  selectRole: undefined,
  // 选择角色拥有的权限
  selectRolePermission: [],
  // 选择授权的权限字符串列表
  selectPermissionStrList: [],

  queryParam: {
    ...ModelInitState.queryParam,
    sysName: undefined,
    resourcesType: undefined,
    needAuthorization: '1',
    title: undefined,
    permissionStr: undefined,
  },
  pagination: {
    ...ModelInitState.pagination,
  },
  data: [],
}

@Form.create()
export default class RoleBindPermission extends PureComponent {

  state = {
    ...InitState,
  }

  // 重置状态
  resetState = () => {
    this.setState(InitState);
  }

  // 初始化现实化数据
  initVisibleData = (roleList) => {
    this.findByPage({ pageNo: 0 });
    if (roleList && roleList.length === 1) {
      // 当 roleList.length===1时 设置 selectPermissionStrList 为角色当前已经绑定了的系统
      this.setState({ queryLoading: true });
      findPermissionStrByRole(roleList[0].name).then(permissionStrList => {
        this.setState({ queryLoading: false, selectPermissionStrList: permissionStrList });
      }).catch(() => this.setState({ queryLoading: false }));
    }
  }

  // 选择的角色 DIV
  getSelectRoleDiv = (roleList) => {
    const { selectRole, selectPermissionStrList } = this.state;
    const { delSelectRole } = this.props;
    const color = '#108ee9';
    const marginBottom = 12;
    const fontSize = 14;
    // 未选择角色
    if (!roleList || roleList.length <= 0) {
      return <Alert message="当前没有选择角色，请选择角色！" type="error" closable={false} />;
    }
    // 选择一个角色
    if (roleList.length === 1) {
      return (
        <div style={{ marginTop: 6, marginBottom: -6 }}>
          <span style={{ marginLeft: 6, fontSize }}>当前选择的角色：</span>
          <Badge offset={[5, 0]} overflowCount={99999999} count={selectPermissionStrList.length}>
            <span style={{ color, fontSize }}>{roleList[0].name}</span>
          </Badge>
        </div>
      );
    }
    // 选择多个角色
    return (
      <div className={styles.divBox}>
        <div className={styles.divBoxTitle}>选择角色</div>
        <Badge offset={[-15, 0]} overflowCount={99999999} count={selectPermissionStrList.length}>
          <Tag
            style={{ marginBottom, fontSize }}
            color={selectRole ? undefined : color}
            onClick={() => this.setState({ selectRole: undefined, selectRolePermission: [] })}
            visible={true}
          >
            统一分配
          </Tag>
        </Badge>
        {roleList.map(role => {
          const lable = cutOffStr(role.name, 16);
          return (
            <Tag
              style={{ marginBottom, fontSize }}
              key={role.id}
              title={lable === role.name ? undefined : role.name}
              color={role.name === selectRole ? color : undefined}
              visible={true}
              closable={roleList.length > 1}
              onClick={e => {
                if (e && e.target && e.target.tagName && lodash.toUpper(e.target.tagName) === "DIV") {
                  this.selectRoleChange(role.name);
                }
              }}
              onClose={() => {
                if (delSelectRole instanceof Function) {
                  delSelectRole(role.id);
                  if (role.name === selectRole) {
                    this.setState({ selectRole: undefined, selectRolePermission: [] });
                  }
                }
              }}
            >
              {lable}
            </Tag>
          );
        })}
      </div>
    );
  }

  // 选择的角色变化
  selectRoleChange = (roleName) => {
    const { selectRole } = this.state;
    if (selectRole === roleName) return;
    this.setState({ queryLoading: true, selectRole: roleName });
    findPermissionStrByRole(roleName).then(permissionStrList => {
      this.setState({ queryLoading: false, selectRolePermission: permissionStrList });
    }).catch(() => this.setState({ queryLoading: false, selectRole }));
  }

  // 选择的权限 DIV
  getPermissionTableDiv = (roleList) => {
    const { queryLoading, selectRole, selectPermissionStrList, selectRolePermission, queryParam, data, pagination } = this.state;
    const { form: { getFieldDecorator }, sysNameList } = this.props;
    const columns = [
      { title: '系统名称', dataIndex: 'sysName', width: 200 },
      { title: '标题', dataIndex: 'title', width: 260, render: val => <Ellipsis title={val} lines={1}>{val}</Ellipsis> },
      { title: '标识', dataIndex: 'permissionStr', width: 260, render: (val, record) => <span title={record.description}>{val}</span> },
      {
        title: '类型', dataIndex: 'resourcesType', width: 160,
        render: (val, record) => {
          let resourcesType = ResourcesTypeMapper[val];
          if (!resourcesType) resourcesType = ResourcesTypeMapper.error;
          if (lodash.indexOf([1], val) !== -1) {
            return this.getUrlPermissionInfo(record);
          } else {
            return resourcesType.label;
          }
        },
      },
      { title: 'URL资源地址', dataIndex: 'resourcesUrl', width: 260, render: val => <Ellipsis title={val} lines={1}>{val}</Ellipsis> },
      // { title: '说明', dataIndex: 'description', width: 130 },
    ];
    const formItemWidth = 174;
    return (
      <Fragment>
        <Form onSubmit={this.formQuery} layout="inline" className={styles.queryForm}>
          <Row gutter={{ md: 0, lg: 0, xl: 0 }}>
            <Form.Item label="所属系统">
              {getFieldDecorator('sysName', { initialValue: queryParam.sysName })(
                <Select placeholder="所属系统" allowClear={true} style={{ width: formItemWidth }} size="small">
                  {sysNameList.map(sysName => (<Select.Option key={sysName} value={sysName}>{sysName}</Select.Option>))}
                </Select>
              )}
            </Form.Item>
            <Form.Item label="权限类型">
              {getFieldDecorator('resourcesType', { initialValue: queryParam.resourcesType })(
                <Select placeholder="权限类型" allowClear={true} size="small">
                  {ResourcesTypeArray.map(item => (<Select.Option key={item.value} value={item.value}>{item.label}</Select.Option>))}
                </Select>
              )}
            </Form.Item>
            <Form.Item label="需要授权">
              {getFieldDecorator('needAuthorization', { initialValue: queryParam.needAuthorization })(
                <Select placeholder="需要授权" allowClear={true} size="small">
                  {NeedAuthorizationArray.map(item => (<Select.Option key={item.value} value={item.value}>{item.label}</Select.Option>))}
                </Select>
              )}
            </Form.Item>
          </Row>
          <Row gutter={{ md: 0, lg: 0, xl: 0 }}>
            <Form.Item label="权限标题">
              {getFieldDecorator('title', { initialValue: queryParam.title })(
                <Input placeholder="权限标题(模糊匹配)" size="small" />
              )}
            </Form.Item>
            <Form.Item label="权限标识">
              {getFieldDecorator('permissionStr', { initialValue: queryParam.permissionStr })(
                <Input placeholder="权限标识(模糊匹配)" size="small" />
              )}
            </Form.Item>
            <Form.Item className={styles.formItemButton}>
              <Button type="primary" htmlType="submit" disabled={queryLoading} size="small">查询</Button>
            </Form.Item>
          </Row>
        </Form>
        <Table
          style={{ margin: '8px 0' }}
          size="small"
          bordered={false}
          // 280
          scroll={{ x: true, y: 410 }}
          rowKey={record => record.permissionStr}
          rowSelection={{
            columnWidth: 50,
            fixed: false,
            selectedRowKeys: (selectRole === undefined) ? selectPermissionStrList : selectRolePermission,
            onChange: (selectedRowKeys) => {
              if (roleList.length === 1 || (roleList.length > 1 && !selectRole)) {
                this.setState({ selectPermissionStrList: selectedRowKeys });
              } else {
                message.info("不能为单个角色分配权限，请使用“统一分配”为所有选择角色授权");
              }
            },
          }}
          columns={columns}
          loading={queryLoading}
          dataSource={data}
          pagination={pagination}
          onChange={this.handleTableChange}
        />
      </Fragment>
    );
  }

  // 获取url权限信息
  getUrlPermissionInfo = (permission) => {
    const { resourcesUrl, targetClass, targetMethod } = permission;
    let { targetExist, needAuthorization, targetMethodParams, resourcesType } = permission;
    resourcesType = ResourcesTypeMapper[resourcesType];
    if (!resourcesType) resourcesType = ResourcesTypeMapper.error;
    if(!targetClass) return <span>{resourcesType.label}</span>;
    targetExist = TargetExistMapper[targetExist]
    if (!targetExist) targetExist = TargetExistMapper.error;
    needAuthorization = NeedAuthorizationMapper[needAuthorization];
    if (!needAuthorization) needAuthorization = NeedAuthorizationMapper.error;
    if (lodash.trim(targetMethodParams) !== "") {
      const params = lodash.split(targetMethodParams, ',');
      targetMethodParams = [];
      params.forEach(item => {
        let param = item;
        if (param.lastIndexOf('.') !== -1) {
          param = param.substring(param.lastIndexOf('.') + 1);
        }
        targetMethodParams.push(lodash.trim(param));
      });
      targetMethodParams = targetMethodParams.join(', ');
    } else {
      targetMethodParams = '--';
    }
    const packageStr = targetClass.substring(0, targetClass.lastIndexOf('.'));
    const classStr = targetClass.substring(targetClass.lastIndexOf('.') + 1);
    const labelStyle = { display: 'inline-block', width: 100 };
    const valueStyle = {};
    const content = (
      <div>
        <div>
          <span style={labelStyle}>URL地址</span>
          <span style={valueStyle}>{resourcesUrl}</span>
        </div>
        <div>
          <span style={labelStyle}>资源存在</span>
          <span style={{ ...valueStyle, color: targetExist.color }}>{targetExist.label}</span>
        </div>
        <div>
          <span style={labelStyle}>需要权限拦截</span>
          <span style={{ ...valueStyle, color: needAuthorization.color }}>{needAuthorization.label}</span>
        </div>
        <div>
          <span style={labelStyle}>代码 package</span>
          <span style={valueStyle}>{packageStr}</span>
        </div>
        <div>
          <span style={labelStyle}>代码 class</span>
          <span style={valueStyle}>{classStr}</span>
        </div>
        <div>
          <span style={labelStyle}>代码方法名</span>
          <span style={valueStyle}>{targetMethod}</span>
        </div>
        <div>
          <span style={labelStyle}>方法参数</span>
          <span style={valueStyle}>{targetMethodParams}</span>
        </div>
      </div>
    );
    return (
      <Popover placement="right" title={`URL权限详情 - {${permission.title}}`} content={content}>
        <a color={resourcesType.color}>{resourcesType.label}</a>
      </Popover>
    );
  }

  // 查询数据
  findByPage = (params) => {
    let { queryParam, pagination } = this.state;
    queryParam = { ...queryParam, ...params };
    this.setState({ queryLoading: true });
    findByPage(queryParam).then(({ records, total, size, current }) => {
      // 保存数据
      pagination = { ...pagination, pageSize: size, current, total };
      this.setState({ queryLoading: false, data: records, queryParam, pagination });
    }).catch(() => {
      this.setState({ queryLoading: false });
    });
  }

  // 查询数据
  formQuery = (e) => {
    if (e) e.preventDefault();
    const { form } = this.props;
    const queryParam = form.getFieldsValue();
    this.findByPage({ ...queryParam, pageNo: 0 });
    // this.setState({ selectPermissionStrList: [] });
  }

  // 表格数据过滤或跳页
  handleTableChange = (pagination, _, sorter) => {
    const queryParam = { pageNo: pagination.current, pageSize: pagination.pageSize };
    // 排序
    if (sorter.field) {
      const sorterMapper = {};
      queryParam.orderField = sorterMapper[sorter.field];
      queryParam.sort = SorterOrderMapper[sorter.order];
    } else {
      queryParam.orderField = undefined;
      queryParam.sort = undefined;
    }
    this.findByPage(queryParam);
  }

  // 确定
  onCreate = () => {
    const { selectPermissionStrList } = this.state;
    const { onOk, roleList } = this.props;
    if (onOk instanceof Function) {
      onOk(roleList.map(role => role.name), selectPermissionStrList);
    }
  }

  render() {
    const { roleList, resetStateFuc, initVisibleDataFuc, visible, confirmLoading, onCancel } = this.props;
    // const { getFieldDecorator, getFieldValue } = form;
    if (resetStateFuc instanceof Function) resetStateFuc(this.resetState);
    if (initVisibleDataFuc instanceof Function) initVisibleDataFuc(this.initVisibleData);
    // const width = 200;
    return (
      <Modal
        width="70%"
        visible={visible}
        style={{ top: 35 }}
        confirmLoading={confirmLoading}
        title="为角色分配权限"
        okText="确定"
        onCancel={onCancel}
        onOk={this.onCreate}
        maskClosable={false}
        bodyStyle={{ padding: '8px 12px 0 12px' }}
      >
        {(roleList && roleList.length > 1) ? <Alert message={`已选择${roleList.length}个角色，将会为这些角色重新分配权限`} type="warning" closable={false} /> : ''}
        {this.getSelectRoleDiv(roleList)}
        <Divider orientation="left" style={{ margin: '12px 0 6px 0' }}>权限列表</Divider>
        {this.getPermissionTableDiv(roleList)}
      </Modal>
    );
  }
}


